<?php

// ---------------------------------- //
// --- BEGIN SYSTEM BOOTSTRAPPING --- //
// - error reporting
// - path constant definition
// - application class inclusion
// - exception class inclusion
// ---------------------------------- //
// error reporting
error_reporting(E_ALL);

// general constants
define("DS", DIRECTORY_SEPARATOR);
define("SITE_PATH", realpath(dirname(__DIR__)));
define("URL", filter_has_var(INPUT_GET, "url") ? filter_input(INPUT_POST, "url") : "");

// path constants
$path_constants = array(
	array("CONFIG", "Configuration"),
	array("VENDOR", "Vendor")
);
foreach ($path_constants as $constant_pair) {
	list($constant_name, $folder_name) = $constant_pair;
	define(sprintf("%s_PATH", strtoupper($constant_name)), implode(DS, array(SITE_PATH, $folder_name)));
}
define("SCHOOL_PATH", implode(DS, array(VENDOR_PATH, "School")));

// application file inclusion
$schoolFiles = array(
	"Application.php",
	"Controller.php",
	"Exception.php",
	"System" => array("Application.php")
);
foreach ($schoolFiles as $schoolDirectory => $schoolFileName) {
	if (is_array($schoolFileName)) {
	$schoolFiles = $schoolFileName;
	foreach ($schoolFiles as $schoolFileName) {
		$schoolFilePath = implode(DS, array(SCHOOL_PATH, $schoolDirectory, $schoolFileName));
		require($schoolFilePath);
	}
	} else {
	$schoolFilePath = implode(DS, array(SCHOOL_PATH, $schoolFileName));
	require($schoolFilePath);
	}
}

// exception handling
set_exception_handler("School\System\Application::exceptionHandler");

// application search path definition
define("AUTOLOAD_PATHS_FILE", "autoload_paths.php");
if (School\System\Application::findFile(CONFIG_PATH, AUTOLOAD_PATHS_FILE, $systemSearchPathsFile)) {
	$systemSearchPaths = include($systemSearchPathsFile);
	School\System\Application::loadSearchPaths($systemSearchPaths);
} else {
	throw new School\System\Exception(sprintf("System autoload search paths file could not be found; system "
	. "configuration directory: '%s', autoload search paths file: '%s'", CONFIG_PATH, AUTOLOAD_PATHS_FILE));
}

// autoload
spl_autoload_register("School\System\Application::autoload");
// -------------------------------- //
// --- END SYSTEM BOOTSTRAPPING --- //
// -------------------------------- //

// ----------------------------------------- //
// --- BEGIN USER-SPECIFIC BOOTSTRAPPING --- //
// - determine which application to instantiate
// - determine which controller to instantiate
// - determine which action to invoke
// ----------------------------------------- //
// user-specific section
define("DEFAULT_APPLICATION", "Index");
define("DEFAULT_CONTROLLER", "Index");
define("DEFAULT_ACTION", "index");
// user-specific application, controller, and action definition
$userApplicationName = DEFAULT_APPLICATION;

// user-specific path constant,
define("USER_PATH", implode(DS, array(SITE_PATH, "User", $userApplicationName)));

$userConfigurationDirectory = implode(DS, array(USER_PATH, "Configuration"));
if (School\System\Application::findFile($userConfigurationDirectory, AUTOLOAD_PATHS_FILE, $userSearchPathsFile)) {
	$userSearchPaths = include($userSearchPathsFile);
	School\System\Application::loadSearchPaths($userSearchPaths);
}
// --------------------------------------- //
// --- END USER-SPECIFIC BOOTSTRAPPING --- //
// --------------------------------------- //

// ----------------------------------- //
// --- BEGIN APPLICATION EXECUTION --- //
// - instantiate the application
// - instantiate the controller
// - invoke the action
// - render the application
// ----------------------------------- //
// application initialisation
$userApplicationClass = sprintf("User\%s\Application", $userApplicationName);
$applicationClass = "School\User\Application";
if (class_exists($userApplicationClass, true)) {
	$applicationClass = $userApplicationClass;
}
$application = new $applicationClass();
printf("<pre>%s</pre>", print_r(get_included_files(), true));
// --------------------------------- //
// --- END APPLICATION EXECUTION --- //
// --------------------------------- //